package com.baozheyangken.ai_learn.controller;

import com.baozheyangken.ai_learn.context.BaseContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

import com.baozheyangken.ai_learn.mapper.AIQuestionMapper;
import com.baozheyangken.ai_learn.mapper.CourseMapper;
import com.baozheyangken.ai_learn.mapper.DifficultyLevelMapper;
import com.baozheyangken.ai_learn.mapper.KnowledgeMapper;
import com.baozheyangken.ai_learn.mapper.QuestionTypesMapper;
import com.baozheyangken.ai_learn.pojo.dto.CourseDTO;
import com.baozheyangken.ai_learn.pojo.entity.AIQuestion;
import com.baozheyangken.ai_learn.pojo.entity.Course;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.bind.annotation.CrossOrigin;

import com.baozheyangken.ai_learn.mapper.DifficultyLevelMapper;
import com.baozheyangken.ai_learn.interceptor.JwtTokenInterceptor;

@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "http://localhost:8081")
public class AIController {
    private static final Logger logger = LoggerFactory.getLogger(AIController.class);
    private final ChatClient chatClient;

    @Autowired
    public AIController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @PostMapping("/generateQuestion")
    public String generateQuestion(
            @RequestParam String subject,
            @RequestParam String difficulty,
            @RequestParam String type) {
        logger.info("Received parameters: subject={}, difficulty={}, type={}", subject, difficulty, type);

        String promptTemplate = """
                    请生成一道{subject}科目{difficulty}难度的{type}题目，要求包含：
                        1. 题目描述
                        2. 选项（选择题需提供）
                        3. **详细解析过程**（包括知识点和解题步骤）
                        4. 答案
                
                        ### 题型分类及结构要求：
                        - 选择题：4个选项（A-D），需说明正确选项的理由及其他选项的错误原因
                        - 填空题：用[ ]标注填空位置，解析需说明填空依据
                        - 简答题：需分点详细解释，解析需包含关键知识点和扩展说明
                        - 计算题：需展示完整计算步骤，解析需说明公式和计算逻辑
                        - 编程题：需提供可运行代码，解析需包含算法思路、复杂度分析和代码解释
                
                        ### 难度分级标准（{difficulty}参数参考）：
                        - 基础：单一知识点，步骤≤2步，无需综合应用
                        - 进阶：2-3个知识点结合，需中等逻辑推导
                        - 拓展：跨章节知识整合，需创新思路或优化方案
                
                        ### 返回格式规范：
                        **题目：** [清晰描述题目内容]
                       \s
                        **选项：**（仅选择题需要） \s
                        A. 选项内容  B. 选项内容 \s
                        C. 选项内容  D. 选项内容 \s
                
                        **解析：** \s
                        - 知识点：[核心考查点] \s
                        - 解题步骤： \s
                          1. [第一步分析] \s
                          2. [第二步分析] \s
                          ... \s
                
                        **答案：** [明确答案，填空题需用[ ]标注]
                
                        ### 示例参考：
                
                        **选择题（基础）** \s
                        题目：Python中，以下哪个语句用于终止当前循环？ \s
                        A. break  B. continue  C. exit  D. stop \s
                
                        解析： \s
                        - 知识点：循环控制语句的区别 \s
                        - 解题步骤： \s
                          1. break用于立即退出整个循环 \s
                          2. continue用于跳过当前循环的剩余部分 \s
                          3. exit是Python解释器退出命令，非循环专用 \s
                          4. stop不是Python的有效关键字 \s
                
                        答案：A \s
                
                        **填空题（进阶）** \s
                        题目：在Java中，创建线程的两种方式是继承[ ]类和实现[ ]接口。 \s
                
                        解析： \s
                        - 知识点：Java多线程实现方式 \s
                        - 解题步骤： \s
                          1. 继承Thread类并重写run()方法 \s
                          2. 实现Runnable接口并实现run()方法 \s
                
                        答案：Thread, Runnable \s
                
                        **简答题（拓展）** \s
                        题目：简述数据库索引的优缺点。 \s
                
                        解析： \s
                        - 知识点：数据库索引的原理和应用 \s
                        - 解题步骤： \s
                          1. 优点：提高查询速度，加速排序和分组操作 \s
                          2. 缺点：占用额外存储空间，降低写操作性能 \s
                          3. 适用场景：经常用于查询条件的字段 \s
                
                        答案： \s
                        优点：加速数据检索，减少I/O操作 \s
                        缺点：增加存储开销，降低数据写入效率 \s
                
                        **计算题（进阶）** \s
                        题目：计算数组 [2, 4, 6, 8, 10] 的平均值。 \s
                
                        解析： \s
                        - 知识点：数组操作和数学计算 \s
                        - 解题步骤： \s
                          1. 求和：2 + 4 + 6 + 8 + 10 = 30 \s
                          2. 计算平均值：30 / 5 = 6 \s
                
                        答案：6 \s
                
                        **编程题（拓展）** \s
                        题目：编写一个函数，判断一个数是否为素数。 \s
                
                        解析： \s
                        - 知识点：素数判断算法、循环优化 \s
                        - 解题步骤： \s
                          1. 素数定义：大于1且只能被1和自身整除 \s
                          2. 优化判断范围：只需检查到平方根 \s
                          3. 特殊情况处理：小于2的数直接返回false \s
                
                        答案： \s
                        ```python
                        def is_prime(n):
                            if n < 2:
                                return False
                            for i in range(2, int(n**0.5) + 1):
                                if n % i == 0:
                                    return False
                            return True
                """;
        PromptTemplate prompt = new PromptTemplate(promptTemplate);
        prompt.add("subject", subject);
        prompt.add("difficulty", difficulty);
        prompt.add("type", type);

        String question = chatClient.call(prompt.create()).getResult().getOutput().getContent();
        return question;
    }

    /*@GetMapping("/chat")
    public Map<String, String> chat(@RequestParam String message) {
        String response = chatClient.call(message);
        return Map.of("response", response);
    }*/

    @Autowired
    private AIQuestionMapper aiQuestionMapper;

    @Autowired
    private DifficultyLevelMapper difficultyLevelMapper;

    @Autowired
    private QuestionTypesMapper questionTypesMapper;

    @Autowired
    private KnowledgeMapper knowledgeMapper;

    @PostMapping("/saveQuestion")
    public String saveQuestion(@RequestBody Map<String, Object> questionData) {
        try {
            logger.info("收到的题目数据: {}", questionData);

            // 从前端数据中提取信息
            String content = (String) questionData.get("content");
            String analysis = (String) questionData.get("analysis");
            String difficultyName = (String) questionData.get("difficulty");
            String typeName = (String) questionData.get("type");
            String knowledgeTitle = (String) questionData.get("knowledge");
            Object courseIdObj = questionData.get("courseId");
            Long courseId = null;
            if (courseIdObj instanceof Integer) {
                courseId = ((Integer) courseIdObj).longValue();
            } else if (courseIdObj instanceof Long) {
                courseId = (Long) courseIdObj;
            }

            if (courseId == null) {
                return "课程 ID 格式错误，请检查输入";
            }

            // 从拦截器获取 userId
            Integer userId = BaseContext.getCurrentId();
            if (userId == null) {
                return "无法从拦截器获取用户 ID，请检查 JWT 校验";
            }

            // 查询难度等级ID
            Integer difficultyId = difficultyLevelMapper.getDifficultyIdByLevelName(difficultyName);
            if (difficultyId == null) {
                return "未找到对应的难度等级，请检查输入";
            }

            // 查询题目类型ID
            Integer typeId = questionTypesMapper.getQuestionTypeIdByTypeName(typeName);
            if (typeId == null) {
                return "未找到对应的题目类型，请检查输入";
            }

            // 查询知识点ID
            List<Long> knowledgeIds = knowledgeMapper.getKnowledgeIdsByTitleAndCourseId(knowledgeTitle, courseId);
            if (knowledgeIds.isEmpty()) {
                return String.format("未找到课程 ID 为 %d 中名为 %s 的知识点，请检查输入", courseId, knowledgeTitle);
            }

            // 创建AIQuestion对象
            AIQuestion aiQuestion = new AIQuestion();
            aiQuestion.setContent(content);
            aiQuestion.setExplanation(analysis);
            aiQuestion.setDifficultyId(difficultyId);
            aiQuestion.setTypeId(typeId);
            aiQuestion.setUserId(Math.toIntExact(userId)); // 设置 user_id

            // 插入题目信息到questions表
            aiQuestionMapper.insert(aiQuestion);
            // 确保插入后能获取到 question_id
            Integer questionId = aiQuestion.getId();
            if (questionId == null) {
                return "无法获取题目 ID，请检查插入操作";
            }

            // 插入知识点关联信息到question_knowledge表
            for (Long knowledgeId : knowledgeIds) {
                knowledgeMapper.insertQuestionKnowledge(questionId, knowledgeId);
            }

            return "题目保存成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "数据插入失败，请检查后重试";
        }
    }

    @Autowired
    private CourseMapper courseMapper;

    @GetMapping("/courses")
    public List<CourseDTO> getAllCourses() {
        List<Course> courses = courseMapper.getAllCourses();
        return courses.stream()
                .map(course -> new CourseDTO(course.getId(), course.getCourseName()))
                .toList();
    }

    @GetMapping("/difficultyLevels")
    public List<String> getAllDifficultyLevels() {
        return difficultyLevelMapper.getAllLevelNames();
    }

    @GetMapping("/questionTypes")
    public List<String> getAllQuestionTypes() {
        return questionTypesMapper.getAllQuestionTypeNames();
    }

    @GetMapping("/knowledgeTitles")
    public List<String> getKnowledgeTitlesByCourseId(@RequestParam Long courseId) {
        return knowledgeMapper.getKnowledgeTitlesByCourseId(courseId);
    }
}